home *** CD-ROM | disk | FTP | other *** search
/ Supercompiler 1997 / SUPERCOMPILER97.iso / Delphi 3.0 / DATA.Z / colorgrd.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1997-01-30  |  16.0 KB  |  530 lines

  1.  
  2. {*******************************************************}
  3. {                                                       }
  4. {       Delphi Visual Component Library                 }
  5. {                                                       }
  6. {       Copyright (c) 1995,97 Borland International     }
  7. {                                                       }
  8. {*******************************************************}
  9.  
  10. unit ColorGrd;
  11.  
  12. {$R-}
  13.  
  14. interface
  15.  
  16. uses Windows, Messages, Classes, Graphics, Forms, Controls, ExtCtrls;
  17.  
  18. const
  19.   NumPaletteEntries = 20;
  20.  
  21. type
  22.   TGridOrdering = (go16x1, go8x2, go4x4, go2x8, go1x16);
  23.  
  24.   TColorGrid = class(TCustomControl)
  25.   private
  26.     FPaletteEntries: array[0..NumPaletteEntries - 1] of TPaletteEntry;
  27.     FClickEnablesColor: Boolean;
  28.     FForegroundIndex: Integer;
  29.     FBackgroundIndex: Integer;
  30.     FForegroundEnabled: Boolean;
  31.     FBackgroundEnabled: Boolean;
  32.     FSelection: Integer;
  33.     FCellXSize, FCellYSize: Integer;
  34.     FNumXSquares, FNumYSquares: Integer;
  35.     FGridOrdering: TGridOrdering;
  36.     FHasFocus: Boolean;
  37.     FOnChange: TNotifyEvent;
  38.     FButton: TMouseButton;
  39.     FButtonDown: Boolean;
  40.     procedure DrawSquare(Which: Integer; ShowSelector: Boolean);
  41.     procedure DrawFgBg;
  42.     procedure UpdateCellSizes(DoRepaint: Boolean);
  43.     procedure SetGridOrdering(Value: TGridOrdering);
  44.     function GetForegroundColor: TColor;
  45.     function GetBackgroundColor: TColor;
  46.     procedure SetForegroundIndex(Value: Integer);
  47.     procedure SetBackgroundIndex(Value: Integer);
  48.     procedure SetSelection(Value: Integer);
  49.     procedure EnableForeground(Value: Boolean);
  50.     procedure EnableBackground(Value: Boolean);
  51.     procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
  52.     procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
  53.     procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
  54.     procedure WMSize(var Message: TWMSize); message WM_SIZE;
  55.     procedure CMCtl3DChanged(var Message: TMessage); message CM_CTL3DCHANGED;
  56.   protected
  57.     procedure KeyDown(var Key: Word; Shift: TShiftState); override;
  58.     procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
  59.       X, Y: Integer); override;
  60.     procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  61.     procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
  62.       X, Y: Integer); override;
  63.     procedure CreateWnd; override;
  64.     procedure Paint; override;
  65.     procedure Change; dynamic;
  66.     function SquareFromPos(X, Y: Integer): Integer;
  67.   public
  68.     constructor Create(AOwner: TComponent); override;
  69.     property ForegroundColor: TColor read GetForegroundColor;
  70.     property BackgroundColor: TColor read GetBackgroundColor;
  71.   published
  72.     property ClickEnablesColor: Boolean read FClickEnablesColor write FClickEnablesColor default False;
  73.     property Ctl3D;
  74.     property DragCursor;
  75.     property DragMode;
  76.     property Enabled;
  77.     property GridOrdering: TGridOrdering read FGridOrdering write SetGridOrdering default go4x4;
  78.     property ForegroundIndex: Integer read FForegroundIndex write SetForegroundIndex default 0;
  79.     property BackgroundIndex: Integer read FBackgroundIndex write SetBackgroundIndex default 0;
  80.     property ForegroundEnabled: Boolean read FForegroundEnabled write EnableForeground default True;
  81.     property BackgroundEnabled: Boolean read FBackgroundEnabled write EnableBackground default True;
  82.     property Font;
  83.     property ParentCtl3D;
  84.     property ParentFont;
  85.     property ParentShowHint;
  86.     property PopUpMenu;
  87.     property Selection: Integer read FSelection write SetSelection default 0;
  88.     property ShowHint;
  89.     property TabOrder;
  90.     property TabStop;
  91.     property Visible;
  92.     property OnChange: TNotifyEvent read FOnChange write FOnChange;
  93.     property OnClick;
  94.     property OnDragDrop;
  95.     property OnDragOver;
  96.     property OnEndDrag;
  97.     property OnEnter;
  98.     property OnExit;
  99.     property OnKeyDown;
  100.     property OnKeyPress;
  101.     property OnKeyUp;
  102.     property OnMouseDown;
  103.     property OnMouseMove;
  104.     property OnMouseUp;
  105.     property OnStartDrag;
  106.   end;
  107.  
  108. implementation
  109.  
  110. uses SysUtils, Consts, StdCtrls;
  111.  
  112. constructor TColorGrid.Create(AOwner: TComponent);
  113. begin
  114.   inherited Create(AOwner);
  115.   ControlStyle := ControlStyle + [csOpaque];
  116.   FGridOrdering := go4x4;
  117.   FNumXSquares := 4;
  118.   FNumYSquares := 4;
  119.   FForegroundEnabled := True;
  120.   FBackgroundEnabled := True;
  121.   Color := clBtnFace;
  122.   Canvas.Brush.Style := bsSolid;
  123.   Canvas.Pen.Color := clBlack;
  124.   SetBounds(0, 0, 100, 100);
  125.   GetPaletteEntries(GetStockObject(DEFAULT_PALETTE), 0, NumPaletteEntries,
  126.     FPaletteEntries);
  127. end;
  128.  
  129. procedure TColorGrid.CreateWnd;
  130. begin
  131.   inherited CreateWnd;
  132.   SetWindowLong(Handle, GWL_STYLE, GetWindowLong(Handle, GWL_STYLE)
  133.     or WS_CLIPSIBLINGS);
  134. end;
  135.  
  136. procedure TColorGrid.DrawSquare(Which: Integer; ShowSelector: Boolean);
  137. var
  138.   WinTop, WinLeft: Integer;
  139.   PalIndex: Integer;
  140.   CellRect: TRect;
  141. begin
  142.   if (Which >=0) and (Which <= 15) then
  143.   begin
  144.     if Which < 8 then
  145.       PalIndex := Which else PalIndex := Which + 4;
  146.     WinTop := (Which div FNumXSquares) * FCellYSize;
  147.     WinLeft := (Which mod FNumXSquares) * FCellXSize;
  148.     CellRect := Bounds(WinLeft, WinTop, FCellXSize, FCellYSize);
  149.     if Ctl3D then
  150.     begin
  151.       Canvas.Pen.Color := clBtnFace;
  152.       with CellRect do Canvas.Rectangle(Left, Top, Right, Bottom);
  153.       InflateRect(CellRect, -1, -1);
  154.       Frame3D(Canvas, CellRect, clBtnShadow, clBtnHighlight, 2);
  155.     end else Canvas.Pen.Color := clBlack;
  156.     with FPaletteEntries[PalIndex] do
  157.     begin
  158.       Canvas.Brush.Color := TColor(RGB(peRed, peGreen, peBlue));
  159.       if Ctl3D then Canvas.Pen.Color := TColor(RGB(peRed, peGreen, peBlue));
  160.     end;
  161.     if not ShowSelector then with CellRect do
  162.       Canvas.Rectangle(Left, Top, Right, Bottom)
  163.     else with CellRect do
  164.     begin
  165.       if Ctl3D then
  166.       begin
  167.         Canvas.Rectangle(Left, Top, Right, Bottom);
  168.         InflateRect(CellRect, -1, -1);
  169.         DrawFocusRect(Canvas.Handle, CellRect);
  170.       end else with Canvas do
  171.       begin
  172.         Pen.Color := clBlack;
  173.         Pen.Mode := pmNot;
  174.         Rectangle(Left, Top, Right, Bottom);
  175.         Pen.Mode := pmCopy;
  176.         Rectangle(Left + 2, Top + 2, Right - 2, Bottom - 2);
  177.       end;
  178.     end;
  179.   end;
  180. end;
  181.  
  182. procedure TColorGrid.DrawFgBg;
  183. var
  184.   TextColor: TPaletteEntry;
  185.   PalIndex: Integer;
  186.   TheText: string;
  187.   OldBkMode: Integer;
  188.   R: TRect;
  189.  
  190.   function TernaryOp(Test: Boolean; ResultTrue, ResultFalse: Integer): Integer;
  191.   begin
  192.     if Test then
  193.       Result := ResultTrue
  194.     else Result := ResultFalse;
  195.   end;
  196.  
  197. begin
  198.   OldBkMode := SetBkMode(Canvas.Handle, TRANSPARENT);
  199.   if FForegroundEnabled then
  200.   begin
  201.     if (FForegroundIndex = FBackgroundIndex) and FBackgroundEnabled then
  202.       TheText := SFB else TheText := SFG;
  203.     if FForegroundIndex < 8 then
  204.       PalIndex := FForegroundIndex else PalIndex := FForegroundIndex + 4;
  205.     TextColor := FPaletteEntries[PalIndex];
  206.     with TextColor do
  207.     begin
  208.       peRed := TernaryOp(peRed >= $80, 0, $FF);
  209.       peGreen := TernaryOp(peGreen >= $80, 0, $FF);
  210.       peBlue := TernaryOp(peBlue >= $80, 0, $FF);
  211.       Canvas.Font.Color := TColor(RGB(peRed, peGreen, peBlue));
  212.     end;
  213.     with R do
  214.     begin
  215.       left := (FForegroundIndex mod FNumXSquares) * FCellXSize;
  216.       right := left + FCellXSize;
  217.       top := (FForegroundIndex div FNumXSquares) * FCellYSize;
  218.       bottom := top + FCellYSize;
  219.     end;
  220.     DrawText(Canvas.Handle, PChar(TheText), -1, R,
  221.        DT_NOCLIP or DT_SINGLELINE or DT_CENTER or DT_VCENTER);
  222.   end;
  223.   if FBackgroundEnabled then
  224.   begin
  225.     if (FForegroundIndex = FBackgroundIndex) and FForegroundEnabled then
  226.       TheText := SFB else TheText := SBG;
  227.     if FBackgroundIndex < 8 then
  228.       PalIndex := FBackgroundIndex else PalIndex := FBackgroundIndex + 4;
  229.     TextColor := FPaletteEntries[PalIndex];
  230.     with TextColor do
  231.     begin
  232.       peRed := TernaryOp(peRed >= $80, 0, $FF);
  233.       peGreen := TernaryOp(peGreen >= $80, 0, $FF);
  234.       peBlue := TernaryOp(peBlue >= $80, 0, $FF);
  235.       Canvas.Font.Color := TColor(RGB(peRed, peGreen, peBlue));
  236.     end;
  237.     with R do
  238.     begin
  239.       left := (FBackgroundIndex mod FNumXSquares) * FCellXSize;
  240.       right := left + FCellXSize;
  241.       top := (FBackgroundIndex div FNumXSquares) * FCellYSize;
  242.       bottom := top + FCellYSize;
  243.     end;
  244.     DrawText(Canvas.Handle, PChar(TheText), -1, R,
  245.       DT_NOCLIP or DT_SINGLELINE or DT_CENTER or DT_VCENTER);
  246.   end;
  247.   SetBkMode(Canvas.Handle, OldBkMode);
  248. end;
  249.  
  250. procedure TColorGrid.EnableForeground(Value: Boolean);
  251. begin
  252.   if FForegroundEnabled = Value then Exit;
  253.   FForegroundEnabled := Value;
  254.   DrawSquare(FForegroundIndex, (FForegroundIndex = FSelection) and FHasFocus);
  255.   DrawFgBg;
  256. end;
  257.  
  258. procedure TColorGrid.EnableBackground(Value: Boolean);
  259. begin
  260.   if FBackgroundEnabled = Value then Exit;
  261.   FBackgroundEnabled := Value;
  262.   DrawSquare(FBackgroundIndex, (FBackgroundIndex = FSelection) and FHasFocus);
  263.   DrawFgBg;
  264. end;
  265.  
  266. function TColorGrid.GetForegroundColor: TColor;
  267. var
  268.   PalIndex: Integer;
  269. begin
  270.   if FForegroundIndex < 8 then
  271.     PalIndex := FForegroundIndex else PalIndex := FForegroundIndex + 4;
  272.   with FPaletteEntries[PalIndex] do
  273.     Result := TColor(RGB(peRed, peGreen, peBlue));
  274. end;
  275.  
  276. function TColorGrid.GetBackgroundColor: TColor;
  277. var
  278.   PalIndex: Integer;
  279. begin
  280.   if FBackgroundIndex < 8 then
  281.     PalIndex := FBackgroundIndex else PalIndex := FBackgroundIndex + 4;
  282.   with FPaletteEntries[PalIndex] do
  283.     Result := TColor(RGB(peRed, peGreen, peBlue));
  284. end;
  285.  
  286. procedure TColorGrid.WMSetFocus(var Message: TWMSetFocus);
  287. begin
  288.   FHasFocus := True;
  289.   DrawSquare(FSelection, True);
  290.   DrawFgBg;
  291.   inherited;
  292. end;
  293.  
  294. procedure TColorGrid.WMKillFocus(var Message: TWMKillFocus);
  295. begin
  296.   FHasFocus := False;
  297.   DrawSquare(FSelection, False);
  298.   DrawFgBg;
  299.   inherited;
  300. end;
  301.  
  302. procedure TColorGrid.KeyDown(var Key: Word; Shift: TShiftState);
  303. var
  304.   NewSelection: Integer;
  305.   Range: Integer;
  306. begin
  307.   inherited KeyDown(Key, Shift);
  308.   NewSelection := FSelection;
  309.   Range := FNumXSquares * FNumYSquares;
  310.   case Key of
  311.     $46, $66:
  312.       begin
  313.         if not FForegroundEnabled and FClickEnablesColor then
  314.         begin
  315.           FForegroundEnabled := True;
  316.           DrawSquare(FForegroundIndex, (FForegroundIndex = FSelection) and FHasFocus);
  317.           FForegroundIndex := -1;
  318.         end;
  319.         SetForegroundIndex(NewSelection);
  320.         SetSelection(NewSelection);
  321.         Click;
  322.       end;
  323.     $42, $62:
  324.       begin
  325.         if not FBackgroundEnabled and FClickEnablesColor then
  326.         begin
  327.           FBackgroundEnabled := True;
  328.           DrawSquare(FBackgroundIndex, (FBackgroundIndex = FSelection) and FHasFocus);
  329.           FBackgroundIndex := -1;
  330.         end;
  331.         SetBackgroundIndex(NewSelection);
  332.         SetSelection(NewSelection);
  333.         Click;
  334.       end;
  335.     VK_HOME: NewSelection := 0;
  336.     VK_UP:
  337.       if FSelection >= FNumXSquares then
  338.         NewSelection := FSelection - FNumXSquares
  339.       else if FSelection <> 0 then
  340.         NewSelection := Range - FNumXSquares + FSelection - 1
  341.       else NewSelection := Range - 1;
  342.     VK_LEFT:
  343.       if FSelection <> 0 then
  344.         NewSelection := FSelection - 1
  345.       else NewSelection := Range - 1;
  346.     VK_DOWN:
  347.       if FSelection + FNumXSquares < Range then
  348.         NewSelection := FSelection + FNumXSquares
  349.       else if FSelection <> Range - 1 then
  350.         NewSelection := FSelection mod FNumXSquares + 1
  351.       else NewSelection := 0;
  352.     VK_SPACE,
  353.     VK_RIGHT:
  354.       if FSelection <> Range - 1 then
  355.         NewSelection := FSelection + 1
  356.       else NewSelection := 0;
  357.     VK_END: NewSelection := Range - 1;
  358.   else
  359.     inherited KeyDown(Key, Shift);
  360.     Exit;
  361.   end;
  362.   Key := 0;
  363.   if FSelection <> NewSelection then
  364.     SetSelection(NewSelection);
  365. end;
  366.  
  367. procedure TColorGrid.WMGetDlgCode(var Message: TWMGetDlgCode);
  368. begin
  369.   Message.Result := DLGC_WANTARROWS + DLGC_WANTCHARS;
  370. end;
  371.  
  372. procedure TColorGrid.WMSize(var Message: TWMSize);
  373. begin
  374.   inherited;
  375.   UpdateCellSizes(False);
  376. end;
  377.  
  378. procedure TColorGrid.CMCtl3DChanged(var Message: TMessage);
  379. begin
  380.   inherited;
  381.   Invalidate;
  382. end;
  383.  
  384. procedure TColorGrid.MouseDown(Button: TMouseButton; Shift: TShiftState;
  385.   X, Y: Integer);
  386. var
  387.   Square: Integer;
  388. begin
  389.   inherited MouseDown(Button, Shift, X, Y);
  390.   FButton := Button;
  391.   FButtonDown := True;
  392.   Square := SquareFromPos(X, Y);
  393.   if Button = mbLeft then
  394.   begin
  395.     if not FForegroundEnabled and FClickEnablesColor then
  396.     begin
  397.       FForegroundEnabled := True;
  398.       DrawSquare(FForegroundIndex, (FForegroundIndex = FSelection) and FHasFocus);
  399.       FForegroundIndex := -1;
  400.     end;
  401.     SetForegroundIndex(Square);
  402.   end
  403.   else begin
  404.     MouseCapture := True;
  405.     if not FBackgroundEnabled and FClickEnablesColor then
  406.     begin
  407.       FBackgroundEnabled := True;
  408.       DrawSquare(FBackgroundIndex, (FBackgroundIndex = FSelection) and FHasFocus);
  409.       FBackgroundIndex := -1;
  410.     end;
  411.     SetBackgroundIndex(Square);
  412.   end;
  413.   SetSelection(Square);
  414.   if TabStop then SetFocus;
  415. end;
  416.  
  417. procedure TColorGrid.MouseMove(Shift: TShiftState; X, Y: Integer);
  418. var
  419.   Square: Integer;
  420. begin
  421.   inherited MouseMove(Shift, X, Y);
  422.   if FButtonDown then
  423.   begin
  424.     Square := SquareFromPos(X, Y);
  425.     if FButton = mbLeft then
  426.       SetForegroundIndex(Square)
  427.     else SetBackgroundIndex(Square);
  428.     SetSelection(Square);
  429.   end;
  430. end;
  431.  
  432. procedure TColorGrid.MouseUp(Button: TMouseButton; Shift: TShiftState;
  433.   X, Y: Integer);
  434. begin
  435.   inherited MouseUp(Button, Shift, X, Y);
  436.   FButtonDown := False;
  437.   if FButton = mbRight then MouseCapture := False;
  438. end;
  439.  
  440. procedure TColorGrid.Paint;
  441. var
  442.   Row, Col, wEntryIndex: Integer;
  443. begin
  444.   Canvas.Font := Font;
  445.   for Row := 0 to FNumYSquares do
  446.     for Col := 0 to FNumXSquares do
  447.     begin
  448.       wEntryIndex := Row * FNumXSquares + Col;
  449.       DrawSquare(wEntryIndex, False);
  450.     end;
  451.   DrawSquare(FSelection, FHasFocus);
  452.   DrawFgBg;
  453. end;
  454.  
  455. procedure TColorGrid.SetBackgroundIndex(Value: Integer);
  456. begin
  457.   if (FBackgroundIndex <> Value) and FBackgroundEnabled then
  458.   begin
  459.     DrawSquare(FBackgroundIndex, (FBackgroundIndex = FSelection) and FHasFocus);
  460.     FBackgroundIndex := Value;
  461.     if FBackgroundIndex = FForegroundIndex then
  462.       DrawSquare(FBackgroundIndex, (FBackgroundIndex = FSelection) and FHasFocus);
  463.     DrawFgBg;
  464.     Change;
  465.   end;
  466. end;
  467.  
  468. procedure TColorGrid.SetForegroundIndex(Value: Integer);
  469. begin
  470.   if (FForegroundIndex <> Value) and FForegroundEnabled then
  471.   begin
  472.     DrawSquare(FForegroundIndex, (FForegroundIndex = FSelection) and FHasFocus);
  473.     FForegroundIndex := Value;
  474.     if FForegroundIndex = FBackgroundIndex then
  475.       DrawSquare(FForegroundIndex, (FForegroundIndex = FSelection) and FHasFocus);
  476.     DrawFgBg;
  477.     Change;
  478.   end;
  479. end;
  480.  
  481. procedure TColorGrid.SetGridOrdering(Value: TGridOrdering);
  482. begin
  483.   if FGridOrdering = Value then Exit;
  484.   FGridOrdering := Value;
  485.   FNumXSquares := 16 shr Ord(FGridOrdering);
  486.   FNumYSquares := 1 shl Ord(FGridOrdering);
  487.   UpdateCellSizes(True);
  488. end;
  489.  
  490. procedure TColorGrid.SetSelection(Value: Integer);
  491. begin
  492.   if FSelection = Value then Exit;
  493.   DrawSquare(FSelection, False);
  494.   FSelection := Value;
  495.   DrawSquare(FSelection, FHasFocus);
  496.   DrawFgBg;
  497. end;
  498.  
  499. function TColorGrid.SquareFromPos(X, Y: Integer): Integer;
  500. begin
  501.   if X > Width - 1 then X := Width - 1
  502.   else if X < 0 then X := 0;
  503.   if Y > Height - 1 then Y := Height - 1
  504.   else if Y < 0 then Y := 0;
  505.   Result := (Y div FCellYSize) * FNumXSquares + (X div FCellXSize);
  506. end;
  507.  
  508. procedure TColorGrid.UpdateCellSizes(DoRepaint: Boolean);
  509. var
  510.   NewWidth, NewHeight: Integer;
  511. begin
  512.   NewWidth := (Width div FNumXSquares) * FNumXSquares;
  513.   NewHeight := (Height div FNumYSquares) * FNumYSquares;
  514.   BoundsRect := Bounds(Left, Top, NewWidth, NewHeight);
  515.   FCellXSize := Width div FNumXSquares;
  516.   FCellYSize := Height div FNumYSquares;
  517.   if DoRepaint then Invalidate;
  518. end;
  519.  
  520. procedure TColorGrid.Change;
  521. begin
  522.   Changed;
  523.   if Assigned(FOnChange) then FOnChange(Self);
  524. end;
  525.  
  526. end.
  527.  
  528.  
  529.  
  530.